package cn.bbstone.pisces2.ui.preference;

import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.jface.preference.BooleanFieldEditor;
import org.eclipse.jface.preference.DirectoryFieldEditor;
import org.eclipse.jface.preference.FieldEditor;
import org.eclipse.jface.preference.FieldEditorPreferencePage;
import org.eclipse.jface.preference.IntegerFieldEditor;
import org.eclipse.jface.preference.RadioGroupFieldEditor;
import org.eclipse.jface.preference.StringFieldEditor;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.widgets.Composite;

import cn.bbstone.pisces2.cmm.Pi2ContextUtil;
import cn.bbstone.pisces2.cmm.UIConst;
import cn.bbstone.pisces2.comm.Const;
import cn.bbstone.pisces2.config.ConfigFactory;
import cn.bbstone.pisces2.config.ConfigModel;
import cn.bbstone.pisces2.ui.base.util.PreferenceUtil;
import cn.bbstone.pisces2.util.NetUtil;

public class ConfigurationPreferencePage extends FieldEditorPreferencePage {

	private RadioGroupFieldEditor runAsFieldEditor;

	// common fields
	private IntegerFieldEditor serverPort;
	private FieldEditor serverHost;
	private FieldEditor fileFilter;
	// server special fields
	private FieldEditor serverRoot;

	// client special fields
	private FieldEditor clientRoot;
	private FieldEditor clientTempFilePostfix;
	private FieldEditor clientFileOverwrite;
	private IntegerFieldEditor clientConnNum;
	private FieldEditor clientRecvBuff;

	private Composite fieldEditorParent;

	IEclipsePreferences preferences;

	public ConfigurationPreferencePage() {
		super(GRID);
		preferences = PreferenceUtil.getPreference(); // DefaultScope.INSTANCE.getNode(FrameworkUtil.getBundle(ConfigurationPreferencePage.class).getSymbolicName());

	}

	@Override
	protected void createFieldEditors() {
		fieldEditorParent = getFieldEditorParent();
		//
		runAsFieldEditor = new RadioGroupFieldEditor(FieldInfoEnum.RUN_AS.getPreferenceName(),
				Messages.basic_preference_runAs, 2,
				new String[][] {
						{ Messages.basic_preference_runAsServer, FieldInfoEnum.RUN_AS_SERVER.getPreferenceName() },
						{ Messages.basic_preference_runAsClient,
								FieldInfoEnum.RUN_AS_CLIENT.getPreferenceName() } },
				fieldEditorParent, false);
		addField(runAsFieldEditor);

		// ---++++++++++++++++++++++++ common(required by server and client)
		serverPort = new IntegerFieldEditor(FieldInfoEnum.SERVER_PORT.getPreferenceName(),
				Messages.basic_preference_serverPort, fieldEditorParent);
		serverPort.setValidRange(1, 65535); // portNum from 1 to 65535
		addField(serverPort);

		serverHost = new StringFieldEditor(FieldInfoEnum.SERVER_HOST.getPreferenceName(),
				Messages.basic_preference_serverHost, 20, fieldEditorParent);
		addField(serverHost);

		// max 500 characters
		fileFilter = new StringFieldEditor(FieldInfoEnum.FLI_FILTER.getPreferenceName(),
				Messages.basic_preference_fileFilter, 50, fieldEditorParent);
		addField(fileFilter);

		// ----++++++++++++++++++++++++ server only
		serverRoot = new DirectoryFieldEditor(FieldInfoEnum.SERVER_ROOT.getPreferenceName(),
				Messages.basic_preference_serverRoot, fieldEditorParent);
		addField(serverRoot);

		// -----++++++++++++++++++++++++ client only
		clientTempFilePostfix = new StringFieldEditor(FieldInfoEnum.CLIENT_FILE_TEMP_POSTFIX.getPreferenceName(),
				Messages.basic_preference_tempPostfix, 10, fieldEditorParent);
		addField(clientTempFilePostfix);

		clientFileOverwrite = new BooleanFieldEditor(FieldInfoEnum.CLIENT_FILE_OVERWRITE.getPreferenceName(),
				Messages.basic_preference_isOverwritten, BooleanFieldEditor.SEPARATE_LABEL,
				fieldEditorParent);
		addField(clientFileOverwrite);
		addField(clientFileOverwrite);

		clientConnNum = new IntegerFieldEditor(FieldInfoEnum.CLIENT_CONN_NUM.getPreferenceName(),
				Messages.basic_preference_clientNum, fieldEditorParent);
		clientConnNum.setValidRange(1, 100);
		addField(clientConnNum);

		clientRecvBuff = new StringFieldEditor(FieldInfoEnum.CLIENT_RECV_BUFF.getPreferenceName(),
				Messages.basic_preference_recvBuff, 10, fieldEditorParent);
		addField(clientRecvBuff);

		clientRoot = new DirectoryFieldEditor(FieldInfoEnum.CLIENT_ROOT.getPreferenceName(),
				Messages.basic_preference_clientRoot, fieldEditorParent);
		addField(clientRoot);

		initState();
	}

	private void initState() {
		// p1 field value
		String runAs = runAsFieldEditor.getSelectionValue();
		if (runAs == null) {
			// p2 context value
			runAs = Pi2ContextUtil.getRunAs();
		}

		if (Pi2ContextUtil.isRunning()) {
			// disabled all fields
			disableCommonFiledEditors();
			disableServerFieldEditors();
			disableClientFieldEditors();
		} else { // not runnin
			// enabled common fields
			enableCommonFiledEditors();
			// p3 preference stored value
			runAs = preferences.get(FieldInfoEnum.RUN_AS.getPreferenceName(), UIConst.RUN_AS_SERVER);
			if (runAs == null || UIConst.RUN_AS_SERVER.equals(runAs)) { // enabled server fields
				enableServerFiledEditors();
				disableClientFieldEditors();
			} else {// enabled client fields
				enableClientFiledEditors();
				disableServerFieldEditors();
			}
		}

	}

	private void enableCommonFiledEditors() {
		runAsFieldEditor.setEnabled(true, fieldEditorParent);
		serverPort.setEnabled(true, fieldEditorParent);
		serverHost.setEnabled(true, fieldEditorParent);
		fileFilter.setEnabled(true, fieldEditorParent);

	}

	private void disableCommonFiledEditors() {
		runAsFieldEditor.setEnabled(false, fieldEditorParent);
		serverPort.setEnabled(false, fieldEditorParent);
		serverHost.setEnabled(false, fieldEditorParent);
		fileFilter.setEnabled(false, fieldEditorParent);
	}

	private void enableClientFiledEditors() {
		clientTempFilePostfix.setEnabled(true, fieldEditorParent);
		clientFileOverwrite.setEnabled(true, fieldEditorParent);
		clientConnNum.setEnabled(true, fieldEditorParent);
		clientRecvBuff.setEnabled(true, fieldEditorParent);
		
		clientRoot.setEnabled(true, fieldEditorParent);
//		preferences.put(FieldInfoEnum.SERVER_ROOT.getPreferenceName(), UIConst.EMPTY_STR);
//		try {
//			preferences.flush();
//		} catch (BackingStoreException e) {
//		}
	}

	private void disableClientFieldEditors() {
		clientTempFilePostfix.setEnabled(false, fieldEditorParent);
		clientFileOverwrite.setEnabled(false, fieldEditorParent);
		clientConnNum.setEnabled(false, fieldEditorParent);
		clientRecvBuff.setEnabled(false, fieldEditorParent);
		
		clientRoot.setEnabled(false, fieldEditorParent);
//		preferences.put(FieldInfoEnum.SERVER_ROOT.getPreferenceName(), UIConst.EMPTY_STR);
	}

	private void enableServerFiledEditors() {
		serverRoot.setEnabled(true, fieldEditorParent);
//		preferences.put(FieldInfoEnum.CLIENT_ROOT.getPreferenceName(), UIConst.EMPTY_STR);
//		try {
//			preferences.flush();
//		} catch (BackingStoreException e) {
//		}
	}

	private void disableServerFieldEditors() {
		serverRoot.setEnabled(false, fieldEditorParent);
//		preferences.put(FieldInfoEnum.SERVER_ROOT.getPreferenceName(), UIConst.EMPTY_STR);
	}
	
	private void setServerHostToLocal() {
		String host = NetUtil.getLocalHostAddress();
		preferences.put(FieldInfoEnum.SERVER_HOST.getPreferenceName(), host);
	}
	
	private void setServerHostToDefault() {
		ConfigModel serverConfigModel = ConfigFactory.loadConfigs(Const.SERVER);
		String host = serverConfigModel.getServerHost();
		preferences.put(FieldInfoEnum.SERVER_HOST.getPreferenceName(), host);
	}

	@Override
	public void propertyChange(PropertyChangeEvent event) {
		super.propertyChange(event);
		Object source = event.getSource();
		// check source whether is expected
		if (source instanceof RadioGroupFieldEditor) {
			RadioGroupFieldEditor fe = (RadioGroupFieldEditor) source;
			// check preference name whether is expected
			if (FieldInfoEnum.RUN_AS.getPreferenceName().equals(fe.getPreferenceName())) {
				String newValue = (String) event.getNewValue();
				// value really change
				if (!event.getNewValue().equals(event.getOldValue())) {
					if (UIConst.RUN_AS_SERVER.equals(newValue)) {
						disableClientFieldEditors();
						enableServerFiledEditors();
//						setServerHostToLocal();
					} else {
						disableServerFieldEditors();
						enableClientFiledEditors();
//						setServerHostToDefault();
					}
					Pi2ContextUtil.setRunAs(newValue);
				}
			}
		}
	}

}
